{ TFieldDescriptor }
function TFieldDescriptor.DateTimeToISODateTimeString(D: TDateTime): String;
begin
  DateTimeToString(Result,ISOFormatSettings.LongDateFormat,D,ISOFormatSettings);
end;

function TFieldDescriptor.DateTimeToLocalDateTimeString(D: TDateTime): String;
begin
     DateTimeToString(Result,LocalFormatSettings.LongDateFormat,D,LocalFormatSettings);
end;

function TFieldDescriptor.LocalDateTimeStringToDateTime(S: String): TDateTime;
begin
  Result:=StrToDateTime(S,LocalFormatSettings);
end;

constructor TFieldDescriptor.Create(AName, ACAption: String;
  AType: TBaseFieldType);
begin
  inherited Create(AType);
  FName:=AName;
  FCaption:=ACAption;
end;

constructor TFieldDescriptor.Create(AName, ACAption: String;
  Pattern: TFieldDescPattern);
var
  i: Integer;
begin
  FName:=AName;
  FCaption:=ACAption;
  FWidth:=Pattern.FWidth;
  FType:=Pattern.FType;
  FPiClist:=TStringList.Create;
  for i:=0 to Pattern.PicList.Count-1 do
      FPiClist.Add(Pattern.PicList.Strings[i]);
  FEditMask:=Pattern.EditMask;
  FVisible:=Pattern.FVisible;
  FPersisten:=Pattern.FPersisten;
  for i:=0 to Length(Pattern.FValidateFunction)-1 do
      AddValidateFunction(Pattern.FValidateFunction[i]);
  for i:=0 to Length(Pattern.FNormalizeFunction)-1 do
      AddNormalizeFunction(Pattern.FNormalizeFunction[i]);
end;

function TFieldDescriptor.ValidateEditMask(const Value: String;
  var Couse: string): Boolean;
 var
   MEdit:TMaskEdit;
 begin
   if FEditMask = '' then
     begin
          Result:=true;
          exit;
     end;
   MEdit:=TMaskEdit.Create(Nil);
   MEdit.EditMask:=FEditMask;
   MEdit.Text:=Value;
   try
     MEdit.ValidateEdit;
     Result:=True;
   except
     Result:=False;
     Couse:=Format(fstrValueUnValid,[FCaption,Value,Format(fstrValueUnmasked,[FEditMask])]);
   end;
   MEdit.Free;
end;

function TFieldDescriptor.Validate(var Value: String; var Couse: string
  ): Boolean;
var
  ACouse:String;
  i: Integer;
begin
  Result:=True;
  Normalize(Value);
  for i:= 0 to Length(FValidateFunction) - 1 do
  begin
    Result:= FValidateFunction[i](Value,ACouse);
    if NOT Result then
      Couse:=Format(fstrValueUnValid,[FCaption,Value,ACouse]);
      Exit;
  end;
end;

function TFieldDescriptor.GetContext(Value: String): String;
begin
  Result:=Format(fstrConverErrFildContext,[FName,Value,BaseFieldTypeDesc[FType]]);
end;

function TFieldDescriptor.GetContext(Value: TDataSetField): String;
begin
  Result:=Format(fstrConverErrFildContext,[FName,('DataSet.Fields["'+Value.FieldName+'"].AsString='+Value.AsString),BaseFieldTypeDesc[FType]]);
end;

function TFieldDescriptor.GetContext(Value: TDOMElement): String;
begin
  Result:=Format(fstrConverErrFildContext,[FName,'NodeName='+Value.NodeName+' Value='+Value.GetAttribute('Value'),BaseFieldTypeDesc[FType]]);
end;

function TFieldDescriptor.XmlQName: string;
begin
  Result:=nsField+':'+FName;
end;

procedure TFieldDescriptor.Normalize(var Value: String);
var
  i: Integer;
begin
   for i:=0 to Length(FNormalizeFunction)-1 do
       VAlue:=FNormalizeFunction[i](Value);
end;


function TFieldDescriptor.ToXMLString(Value: String): String;
function GetXml(Name,Value:String):String;
begin
  Result:='<'+Name+' "value="'+Value+'"/>'
end;
begin
   Normalize(Value);
   try
     case FType of
       bdtText:Result:=GetXml(XmlQName(),Value);
       bdtInt:Result:=GetXml(XmlQName(),IntToStr(StrToInt(Value)));
       bdtFloat:Result:=GetXml(XmlQName(),FloatToStr(StrToFloat(Value),ISOFormatSettings));
       bdtDate:Result:=GetXml(XmlQName(),DateTimeToISODateTimeString(StrToDateTime(Value)));
      else
         Raise ETransferObjFildTypeNotEmplement.Create(fstrUnknounFildTypeErr,Format(fstrUnknounFildTypeErrContext,['TFieldDescriptor.ToXMLString',FType]),nil);
     end;
   except
     on E:EConvertError do Raise EFieldDescErr.Create(fstrConverErrNative,GetContext(Value),E);
     on E:Exception do Raise E;
   end;
end;

function TFieldDescriptor.ToXMLNode(const XMLDoc: TXMLDocument;
Value: String): TDOMElement;
begin
//Result:=XMLDoc.CreateElement(XmlFullName());
Result:=XMLDoc.CreateElementNS(nsFieldURI,XmlQName());
try
    case FType of
      bdtText:Result.SetAttribute('Value',Value);
      bdtInt:Result.SetAttribute('Value',IntToStr(StrToInt(Value)));
      bdtFloat:Result.SetAttribute('Value',FloatToStr(StrToFloat(Value),ISOFormatSettings));
      bdtDate:Result.SetAttribute('Value',DateTimeToISODateTimeString(StrToDateTime(Value)));
      else
          Raise ETransferObjFildTypeNotEmplement.Create(fstrUnknounFildTypeErr,Format(fstrUnknounFildTypeErrContext,['TFieldDescriptor.ToXMLNode',FType]),nil);
      end;
    except
      on E:EConvertError do Raise EFieldDescErr.Create(fstrConverErrNative,GetContext(Value),E);
      on E:Exception do Raise E;
    end;
end;


function TFieldDescriptor.ToSQLString(Value: String): String;
begin
  Normalize(Value);
try
      case FType of
        bdtText:Result:=''''+Value+'''';
        bdtInt:Result:=IntToStr(StrToInt(Value));
        bdtFloat:Result:=FloatToStr(StrToFloat(Value),ISOFormatSettings);
        bdtDate:Result:=DateTimeToISODateTimeString(StrToDateTime(Value));
        else
            Raise ETransferObjFildTypeNotEmplement.Create(fstrUnknounFildTypeErr,Format(fstrUnknounFildTypeErrContext,['TFieldDescriptor.ToSQLString',FType]),nil);
        end;
      except
        on E:EConvertError do Raise EFieldDescErr.Create(fstrConverErrNative,GetContext(Value),E);
        on E:Exception do Raise E;
      end;
end;

function TFieldDescriptor.SelectSqlStr: String;
begin
case FType of
  bdtText:Result:=' TRIM('+FName+') ';
  bdtInt:Result:=FName;
  bdtFloat:Result:=FName;
  bdtDate:Result:=FName;
  else
      Raise ETransferObjFildTypeNotEmplement.Create(fstrUnknounFildTypeErr,Format(fstrUnknounFildTypeErrContext,['TFieldDescriptor.SelectSqlStr',FType]),nil);
  end;
end;


function TFieldDescriptor.FromSQLFildVAlue(const SQLVAlue: TDataSetField): String;
begin
try
case FType of
  bdtText:Result:=SQLVAlue.AsString;
  bdtInt:Result:=IntToStr(StrToInt(SQLVAlue.AsString));
  bdtFloat:Result:=FloatToStr(StrToFloat(SQLVAlue.AsString,ISOFormatSettings),LocalFormatSettings);
  bdtDate:Result:=DateTimeToLocalDateTimeString(StrToDateTime(SQLVAlue.AsString,ISOFormatSettings));
  else
      Raise ETransferObjFildTypeNotEmplement.Create(fstrUnknounFildTypeErr,Format(fstrUnknounFildTypeErrContext,['TFieldDescriptor.FromSQLFildVAlue',FType]),nil);
  end;
except
  on E:EConvertError do Raise EFieldDescErr.Create(fstrConverErrNative,GetContext(Result),E);
  on E:Exception do Raise E;
end;
end;

constructor TFieldDescriptor.Create(AType: TBaseFieldType);
begin
  inherited Create(AType);
end;


function TFieldDescriptor.FromXMLNode(Node: TDOMElement):String;
begin
try
if Node.LocalName<>FName then Raise Exception.Create('Error tag name for TableRow. Expect ('+FName+') found ('+Node.TagName+')');
case FType of
  bdtText:Result:=Node.GetAttribute('Value');
  bdtInt:Result:=IntToStr(StrToInt(Node.GetAttribute('Value')));
  bdtFloat:Result:=FloatToStr(StrToFloat(Node.GetAttribute('Value'),ISOFormatSettings),LocalFormatSettings);
  bdtDate:Result:=DateTimeToLocalDateTimeString(StrToDateTime(Node.GetAttribute('Value'),ISOFormatSettings));
  else
      Raise ETransferObjFildTypeNotEmplement.Create(fstrUnknounFildTypeErr,Format(fstrUnknounFildTypeErrContext,['TFieldDescriptor.FromXMLNode',FType]),nil);
  end;
except
  on E:EConvertError do Raise ETransferObjFildError.Create(fstrConverErrNative,GetContext(Result),E);
  on E:Exception do Raise E;
end;
end;


